<?php
/**
 * Created by 784855684@qq.com.
 * Link: https://github.com/lichtung/wshore
 * User: linzh
 * Date: 7/8/17
 * Time: 11:27 AM
 */
declare(strict_types=1);


namespace application\module\admin\addon\wechat\entity;


use application\module\admin\addon\Wechat;
use application\module\admin\addon\wechat\throws\InvalidMessageException;
use application\module\admin\addon\wechat\throws\UnsupportMessageTypeException;
use wshore\core\Storage;
use wshore\helper\Network;
use wshore\helper\traits\Magic;
use wshore\throws\io\FileWriteFailedException;
use wshore\throws\NetworkException;

/**
 * Class Message
 *
 *
 * @property string $to         消息发送者openid
 * @property string $from       消息接受者,即公众号ID
 * @property string $sendtime   发送时间
 * @property string $type       消息类型,目前支持text,image,event
 * @property string $msgid      消息ID
 * @property string $content    消息内容,图片消息类型时为存放路径
 *
 * @property string $mediaId    媒体ID
 * @property string $picUrl     图片消息URL
 * @property string $event      事件类型
 *
 * @package application\module\admin\addon\wechat\entity
 */
class Message
{
    use Magic;

    /**
     * Message constructor.
     * @param array $data
     * @throws InvalidMessageException
     * @throws UnsupportMessageTypeException
     */
    public function __construct(array $data)
    {
        if (empty($data['MsgType'])) {
            throw new InvalidMessageException(var_export($data, true));
        }
        $this->to = $data['ToUserName'];
        $this->from = $data['FromUserName'];
        $this->sendtime = (int)$data['CreateTime'];
        $this->type = $data['MsgType'];
        # 非文本消息 hold
        $this->msgid = $data['MsgId']??0;

        switch ($data['MsgType']) {
            case 'text':
                $this->content = Wechat::encode($data['Content']);
                break;
            case 'image':
                # 图片消息 hold
                $this->mediaId = $data['MediaId'];
                $this->picUrl = $data['PicUrl'];
                $this->content = $this->storeImage2Local();
                break;
            case 'event':
                $this->event = $data['Event'];
                break;
            default:
                throw new UnsupportMessageTypeException($data['MsgType']);
        }
    }

    /**
     * @return string 返回图片保存的路径
     * @throws FileWriteFailedException
     * @throws NetworkException
     */
    private function storeImage2Local(): string
    {
        $content = Network::get($this->picUrl);
        if ($content) {
            $path = '/upload/wechat/' . $this->to . '/' . $this->from . '/' . $this->sendtime . '.jpg';
            $file = WS_PATH_PUBLIC . $path;
            if (Storage::write($file, $content)) {
                return $path;
            } else {
                throw new FileWriteFailedException($file);
            }
        }
        throw new NetworkException($this->picUrl . ' download failed');
    }

}